package service

import (
	set "github.com/deckarep/golang-set"
	"github.com/gogf/gf/errors/gerror"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"shrimp-blog-server/app/dao"
	"shrimp-blog-server/app/model"
)

func (*SubjectService) AddSubject(req *ghttp.Request, subjects ...model.SubjectRequest) {
	if len(subjects) == 0 {
		responses.ErrorResponseExit(req, "请输入专题信息")
	}
	var subjectModel []model.Subject

	oldSet := set.NewSet()
	for i := range subjects {
		oldSet.Add(subjects[i].Name)
	}

	err := dao.Subject.DB().Model(dao.Subject.Table).Where(g.Map{dao.Subject.Columns.Name: oldSet.ToSlice()}).WhereNotNull(dao.Label.Columns.DeleteTime).Unscoped().Scan(&subjectModel)
	if err != nil {
		panic(gerror.Wrap(err, "查询主题失败"))
	}

	if len(subjectModel) > 0 {
		// 先更新
		tx, err := dao.Subject.DB().Begin()
		if err != nil {
			panic(gerror.Wrap(err, "开启事务失败"))
		}
		for i := range subjectModel {
			subjectModel[i].DeleteTime = nil
			subjectModel[i].Status = model.ShowStatus
			_, err := dao.Subject.DB().Model(dao.Subject.Table).TX(tx).Where(g.Map{dao.Subject.Columns.Id: subjectModel[i].Id}).Update(g.Map{dao.Subject.Columns.DeleteTime: nil, dao.Subject.Columns.Status: model.ShowStatus})
			if err != nil {
				g.Log("添加主题").Error(gerror.Wrap(err, "更新主题失败"))
			}
		}

		// 插入后插入
		newSet := set.NewSet()
		for i := range subjectModel {
			newSet.Add(subjectModel[i].Name)
		}

		// 不一样的标签
		difference := oldSet.Difference(newSet)
		if len(difference.ToSlice()) > 0 {
			subjectModelList := make([]model.Subject, 0)
			for i := range difference.ToSlice() {
				subjectModelList = append(subjectModelList, model.Subject{Name: difference.ToSlice()[i].(string)})
			}
			_, err = dao.Subject.Insert(subjectModelList...)
			if err != nil {
				g.Log("添加主题").Error(gerror.Wrap(err, "添加主题失败"))
				responses.ErrorResponseExit(req, "插入标签失败")
				req.ExitAll()
			}
		}

		if err != nil {
			err := tx.Rollback()
			if err != nil {
				panic(gerror.Wrap(err, "回滚事务失败"))
			}
		} else {
			err := tx.Commit()
			if err != nil {
				panic(gerror.Wrap(err, "提交事务失败"))
			}
		}
	} else { // 没有重复的主题直接插入
		for i := range subjects {
			subjectModel = append(subjectModel, model.Subject{Name: subjects[i].Name, Status: model.ShowStatus})
		}
		_, err := dao.Subject.Insert(subjectModel...)
		if err != nil {
			g.Log("添加主题").Error(gerror.Wrap(err, "添加主题失败"))
			responses.ErrorResponseExit(req, "添加主题失败")
		}
	}

	responses.SuccessResponse(req)
}

func (*SubjectService) UpdateSubject(req *ghttp.Request, subject ...model.SubjectRequest) {
	if len(subject) == 0 {
		responses.ErrorResponseExit(req, "请输入专题信息")
	}
	tx, err := dao.Subject.DB().Begin()
	if err != nil {
		panic(gerror.Wrap(err, "开启事务失败"))
	}
	for i := range subject {
		_, err := dao.Subject.Update(tx, subject[i].Convert())
		if err != nil {
			g.Log("修改标签失败").Error(err)
		}
	}
	if err != nil {
		err := tx.Rollback()
		if err != nil {
			panic(gerror.Wrap(err, "回滚事务失败"))
		}
	} else {
		err := tx.Commit()
		if err != nil {
			panic(gerror.Wrap(err, "提交事务失败"))
		}
	}
	responses.SuccessResponse(req)
}
func (*SubjectService) DeleteSubject(req *ghttp.Request, id ...uint) {
	if len(id) == 0 {
		responses.ErrorResponseExit(req, "请输入专题id")
	}
	models := make([]model.Subject, len(id))
	for i, v := range id {
		models[i].Id = v
		models[i].Status = model.NotShowStatus
	}
	affected, err := dao.Subject.Delete(models...)
	if err != nil {
		g.Log("删除专题失败").Error(err)
		panic(gerror.Wrap(err, "删除专题失败"))
	}
	if affected == 0 {
		responses.ErrorResponseExit(req, "删除专题失败")
	}
	responses.SuccessResponse(req)
}

func (*SubjectService) GetSubjectByID(req *ghttp.Request, id ...uint) {
	var subject []model.Subject
	var err error
	if len(id) == 0 {
		err = dao.Subject.DB().Model(dao.Subject).OrderDesc(dao.Subject.Columns.Id).Scan(&subject)
	} else {
		subject, err = dao.Subject.GetModelById(id...)
	}
	if err != nil {
		g.Log("获取专题失败").Error(err)
		panic(gerror.Wrap(err, "获取专题失败"))
	}
	responses.Json(req, successCode, successMessage, subject)
}

func (*SubjectService) GetSubjectPage(req *ghttp.Request, page model.Page) {
	result, err := dao.Subject.GetModelsByPage(page.Page, page.Size)
	if err != nil {
		g.Log("查询主题失败").Error(err)
		panic(err)
	}
	if result == nil {
		responses.ErrorResponseExit(req, "主题列表为空")
	}
	subjectResponse := result[0].ConvertPage(result, page)
	subjectResponse.Page.Total, err = dao.Subject.DB().Model(dao.Subject.Table).Count()
	if err != nil {
		panic(gerror.Wrap(err, "统计数量失败"))
	}
	responses.Json(req, successCode, successMessage, subjectResponse)
}
